Skip to content

Conversation

@milanatshopify
Copy link
Contributor

@milanatshopify milanatshopify commented Aug 23, 2025

Claude only so far, not human reviewed yet.

  1. Configuration (config.go)
  • Added PerTableComposite to CascadingPaginationColumnConfig for specifying composite keys
  • Added CompositePaginationColumnsFor() method to retrieve composite columns
  • Supports up to 3 columns per composite key
  1. Table Schema (table_schema_cache.go)
  • Added fields for composite pagination: IsCompositePagination, CompositePaginationColumns, CompositePaginationIndexes
  • Added setupPaginationColumns() to configure both single and composite pagination
  • Added validation for BIGINT and VARCHAR(255) column types
  • Created maxCompositePaginationKey() to get max values for composite keys
  • Updated MaxPaginationKeys() to return both single and composite max keys
  1. SQL Query Generation (cursor.go)
  • Created CompositeKey type for handling multi-column keys
  • Added BuildCompositeTupleComparison() for generating proper WHERE clauses
  • Created DefaultBuildSelectComposite() for composite key queries
  • Generates queries like: WHERE (col1, col2) > (val1, val2) OR (col1 = val1 AND col2 > val2)
  1. Cursor (cursor.go)
  • Added composite key fields to Cursor struct
  • Created NewCompositeCursor() constructor
  • Updated Fetch() to handle composite key queries
  • Added updateCompositePosition() to track progress
  1. Row Batch (row_batch.go)
  • Added composite pagination support fields
  • Tracks multiple pagination column indexes
  1. State Tracker (state_tracker.go)
  • Added LastSuccessfulCompositePaginationKeys to track composite key progress
  • Created methods for updating and retrieving composite key positions
  • Updated serialization to preserve composite key state
  1. Data Iterator (data_iterator.go)
  • Updated to handle both single and composite pagination
  • Stores composite max keys for table iteration
  • Creates appropriate cursors based on table configuration
  1. Type Handling
  • Supports BIGINT (uint64) and VARCHAR(255) (string) columns
  • Proper type conversions in scan operations
  • Composite key comparison handles both numeric and string types

Example Configuration

{
"CascadingPaginationColumnConfig": {
"PerTableComposite": {
"mydb": {
"orders": ["customer_id", "order_date", "order_id"],
"transactions": ["account_id", "timestamp", "seq_num"]
}
},
"PerTable": {
"mydb": {
"legacy_table": "id"
}
},
"FallbackColumn": "id"
}
}

Benefits

  1. No Secondary Index Required: Tables with composite primary keys no longer need a UNIQUE KEY on id
  2. Natural Ordering: Uses the table's actual primary key for iteration
  3. Backward Compatible: Single column pagination still works as before
  4. Flexible Configuration: Can mix single and composite pagination per table

Limitations

  1. Maximum 3 columns per composite key
  2. Only supports BIGINT and VARCHAR(255) column types
  3. Verifiers need additional work for full composite key support
  4. Performance may be slightly slower than single column pagination due to complex WHERE clauses

The implementation provides a solid foundation for composite key pagination while maintaining backward compatibility with existing Ghostferry deployments.

@milanatshopify milanatshopify marked this pull request as draft August 23, 2025 00:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant